#pragma once

#include <iostream>
#include <string>
#include <unistd.h>
#include <functional>
#include "InetAddr.hpp"

#define ListenConnection 0
#define NormalConnection 1

class Connection;
class Reactor;
using handler_t = std::function<void(Connection *conn)>;

// 令服务器一切皆connection
class Connection
{
private:
    int _sockfd;
    uint32_t _events;
    std::string _inbuffer;
    std::string _outbuffer;
    int _type;

public:
    handler_t _recver;
    handler_t _sender;
    handler_t _excepter;

    Reactor *_R; // 回指自己属于的reactor
    InetAddr _addr;

public:
    Connection(int sockfd) : _sockfd(sockfd) {}
    ~Connection() {}

    void RegisterHandler(handler_t recver, handler_t sender, handler_t excepter)
    {
        _recver = recver;
        _sender = sender;
        _excepter = excepter;
    }

    void SetEvent(uint32_t events) { _events = events; }
    void SetType(int type) { _type = type; }
    void AppendInbuffer(const std::string &in) { _inbuffer += in; }
    void AppendOutbuffer(const std::string &out) { _outbuffer += out; }
    void DiscardInbuffer(int n) { _inbuffer.erase(0, n); }
    void DiscardOutbuffer(int n) { _outbuffer.erase(0, n); }
    void SetReactor(Reactor *R) { _R = R; }
    void SetAddr(const InetAddr &addr) { _addr = addr; }

    int Sockfd() { return _sockfd; }
    uint32_t Events() { return _events; }
    int Type() { return _type; }
    std::string &Inbuffer() { return _inbuffer; }
    std::string &Outbuffer() { return _outbuffer; }

    void Close()
    {
        if (_sockfd >= 0)
            ::close(_sockfd);
    }
};
